﻿package com.game.tile
{
    import com.dusk.net.AssetManager;
    import com.game.engine.nape.Nape;
    import com.game.tile.display.TMXLayer;
    import com.game.tile.model.LayerVO;
    import com.game.tile.model.ObjectLayerVO;
    import com.game.tile.model.TileLayerVO;
    import com.game.tile.model.Tileset;
    import com.game.tile.utils.TMXResource;
    import com.hurlant.util.Base64;
    
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.DisplayObject;
    import flash.display.Loader;
    import flash.display.LoaderInfo;
    import flash.display.MovieClip;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.IOErrorEvent;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.net.URLRequest;
    import flash.utils.ByteArray;
    import flash.utils.Dictionary;
    import flash.utils.getQualifiedSuperclassName;
    
    public class TMXTileMap extends EventDispatcher 
    {

        public static const ORIENTATION_NORMAL:String = "orientation";
        public static const ORIENTATION_ISO:String = "isometric";
        public static const LAYER_WALKABLE:String = "walkable";

        private var _mapHeight:int;
        private var _mapWidth:int;
        private var _tileHeight:int;
        private var _tileWidth:int;
        private var _XML:XML;
        private var _layers:Vector.<TMXLayer>;
        protected var _tilesets:Vector.<Tileset>;
        protected var _path:String;
        private var _tileInd:int;
        protected var _imgTotal:uint = 0;
        protected var _imgInd:uint = 0;
        private var _layerVos:Vector.<LayerVO>;
        private var _needDrawLayer:Array;
        private var _objectLayers:Vector.<ObjectLayerVO>;
        public var standAlone:Boolean;
        private var _needLoadAssets:Array = [];
        private var mouseEnabled:Boolean;
        private var _orientation:String;
        private var _display:Sprite = new Sprite();
        public var properties:Dictionary;
        //前景，会遮在人物身前
        private var _layer4:Sprite = new Sprite();
        //地板层
        private var _layer3:Sprite = new Sprite();
        //地板层
        private var _layer2:Sprite = new Sprite();
        //最底层，存放背景图片、图片特效之类的东西
        private var _layer1:Sprite = new Sprite();
        public var onlyParse:Boolean = false;
        private var tmxRes:TMXResource;

        public function TMXTileMap()
        {
            _layers = new Vector.<TMXLayer>();
            _objectLayers = new Vector.<ObjectLayerVO>();
            _layerVos = new Vector.<LayerVO>();
        }

        public function get layer4():Sprite
        {
            return _layer4;
        }

        public function get layer3():Sprite
        {
            return _layer3;
        }

        public function get layer2():Sprite
        {
            return _layer2;
        }

        public function get layer1():Sprite
        {
            return _layer1;
        }

        public function get Display():Sprite
        {
            return _display;
        }

        public function get needLoadAssets():Array
        {
            return _needLoadAssets;
        }

        public function load(_arg_1:String):void
        {
            var _local_2:int;
            var _local_3:Array = _arg_1.split("/");
            _path = "";
            _local_2 = 0;
            while (_local_2 < _local_3.length - 1)
            {
                _path = _path + (_local_3[_local_2] + "/");
                _local_2++;
            }
            AssetManager.getIns().loadAsset(_arg_1, "bytes", null,onC);
        }

        private function onC(_arg_1:AssetItem, _arg_2:Number):void
        {
            trace("地图加载完成)=", _arg_1.url);
            var _local_3:ByteArray = _arg_1.data;
            parse(XML(_local_3.toString()));
            _arg_1.destory();
        }

        public function parse(tmxXMLData:XML):void
        {
            var _local_4:int;
            _XML = tmxXMLData;
            _mapWidth = _XML.@width;
            _mapHeight = _XML.@height;
            _tileHeight = _XML.@tileheight;
            _tileWidth = _XML.@tilewidth;
            _orientation = _XML.@orientation;
            _tilesets = new Vector.<Tileset>();
            properties = new Dictionary();
            for each (var subXML:XML in tmxXMLData.properties.property)
            {
                //初始化地图的小属性
                properties[String(subXML.@name)] = String(subXML.@value);
            }
            //初始化地图的每一层
            for each (var layerXML:XML in tmxXMLData.children())
            {
                initChildern(layerXML);
            }
            _local_4 = 0;
            while (_local_4 < _layerVos.length)
            {
                _local_4++;
            }
            if (!standAlone)
            {
                initTileAsset();
            }
        }

        public function setTileBitmapData(_arg_1:String, _arg_2:BitmapData):void
        {
            if (!_tilesets)
            {
                throw new Error("还没有parse ");
            }
            for each (var _local_3:Tileset in _tilesets)
            {
                if (_local_3.image == _arg_1)
                {
                    _local_3.bitmapData = _arg_2;
                    return;
                }
            }
        }

        private function initChildern(_arg_1:XML):void
        {
            var _local_3:String = _arg_1.name();
            var _local_2:String = _arg_1.@name;
            switch (_local_3)
            {
                case "tileset":
                    if (!onlyParse)
                    {
                        parseTileset(_arg_1);
                    }
                    return;
                case "layer":
                    parseTileLayer(_arg_1);
                    return;
                case "objectgroup":
                    parseObjectLayer(_arg_1);
                    return;
                case "imagelayer":
                    parseImageLayer(_arg_1);
                    return;
                default:
                    return;
            }
        }

        private function initTileAsset():void
        {
            loadTileaAsset();
        }

        private function loadTileaAsset():void
        {
            if (_imgInd >= _tilesets.length)
            {
                DrawLayer();
                return;
            }
            var _local_2:Tileset = _tilesets[_imgInd];
            var _local_3:String = this._path + _local_2.image;
            var _local_1:Loader = new Loader();
            _local_1.load(new URLRequest(_local_3));
            _local_1.contentLoaderInfo.addEventListener("ioError", onIoError);
            _local_1.contentLoaderInfo.addEventListener("complete", onAssetLoadComplete);
        }

        private function onIoError(_arg_1:IOErrorEvent):void
        {
            trace("e: " + _arg_1); //not popped
        }

        private function onAssetLoadComplete(_arg_1:Event):void
        {
            var _local_2:Bitmap = LoaderInfo(_arg_1.currentTarget).loader.content as Bitmap;
            var _local_3:BitmapData = _local_2.bitmapData;
            _tilesets[_imgInd].bitmapData = _local_3;
            _imgInd++;
            loadTileaAsset();
        }

        private function parseTileset(_arg_1:XML):void
        {
            var _local_2:Tileset = new Tileset();
            _local_2.buildFormXMLAttr(_arg_1);
            _tilesets.push(_local_2);
            _needLoadAssets.push(_local_2.image);
        }

        /**
         * 设置tmx资源集
         * @param tmxResBun
         */
        public function setTmxResource(tmxResBun:TMXResource):void
        {
            var _local_9:* = null;
            var _local_3:* = null;
            var _local_5:* = null;
            var _local_10:int;
            var _local_2:* = null;
            var _local_4:* = null;
            var _local_8:* = null;
            var _local_7:Boolean;
            this.tmxRes = tmxResBun;
            parse(tmxResBun.tmx);
            if (!_tilesets)
            {
                throw new Error("还没有parse ");
            }
            for each (var _local_6:Tileset in _tilesets)
            {
                _local_9 = tmxResBun.getTileBdByName(_local_6.name);
                _local_6.bitmapData = _local_9;
            }
            _local_10 = 0;
            while (_local_10 < _layerVos.length)
            {
                _local_3 = _layerVos[_local_10];
                if (_local_3.type == "imagelayer")
                {
                    _local_2 = tmxResBun.getImageByName(ImageLayerVO(_local_3).source, _local_3.name);
                    if (_local_2 is BitmapData)
                    {
                        ImageLayerVO(_layerVos[_local_10]).bd = (_local_2 as BitmapData);
                    }
                    else
                    {
                        _local_4 = (_local_2 as Class);
                        if (_local_4)
                        {
                            _local_5 = new _local_4();
                            _local_8 = getQualifiedSuperclassName(_local_5);
                            if (_local_8 == "flash.display::BitmapData")
                            {
                                ImageLayerVO(_layerVos[_local_10]).bd = (_local_5 as BitmapData);
                            }
                            else
                            {
                                if (_local_8 == "flash.display::MovieClip")
                                {
                                    _local_7 = true;
                                    if (_local_3.properties.hasOwnProperty("loop"))
                                    {
                                        _local_7 = _local_3.properties.loop;
                                    }
                                    new MovieClipAdvance(_local_5 as MovieClip, _local_7);
                                    ImageLayerVO(_layerVos[_local_10]).displayObject = (_local_5 as DisplayObject);
                                }
                            }
                        }
                    }
                }
                _local_10++;
            }
        }

        private function parseTileLayer(xml:XML):void
        {
            var _local_7:int;
            var _local_6:int;
            var _local_2:int;
            var vo:TileLayerVO = new TileLayerVO();
            vo.buildFromXMLAttr(xml);
            vo.tileWidth = this._tileWidth;
            vo.tileHeight = this._tileHeight;
            var ba:ByteArray = Base64.decodeToByteArray(xml.data.toString());
            ba.uncompress();
            ba.endian = "littleEndian";
            vo.grid = [];
            _local_7 = 0;
            while (_local_7 < vo.height)
            {
                vo.grid[_local_7] = [];
                _local_6 = 0;
                while (_local_6 < vo.width)
                {
                    _local_2 = ba.readInt();
                    vo.grid[_local_7][_local_6] = _local_2;
                    _local_6++;
                }
                _local_7++;
            }
            vo.type = "tile";
            ba.clear();
            ba = null;
            _layerVos.push(vo);
        }

        private function parseImageLayer(_arg_1:XML):void
        {
            var _local_2:ImageLayerVO = new ImageLayerVO();
            _local_2.buildFormXMLAttr(_arg_1);
            _local_2.type = "imagelayer";
            _layerVos.push(_local_2);
            if (!onlyParse)
            {
                _needLoadAssets.push(_local_2.source);
            }
        }

        private function parseObjectLayer(_arg_1:XML):void
        {
            var _local_2:ObjectLayerVO = new ObjectLayerVO();
            _local_2.buildFormXMLAttr(_arg_1);
            _local_2.type = "objectgroup";
            _objectLayers.push(_local_2);
            _layerVos.push(_local_2);
        }

        public function DrawLayer():void
        {
            var sLayer:* = null;
            var _local_1:* = null;
            _layers = new Vector.<TMXLayer>();
            for (var idx:int = 0;idx < _layerVos.length; idx++)
            {
                sLayer = _layerVos[idx];
                _local_1 = getDataLayerClass(sLayer);
                var layerVO:TMXLayer = new _local_1();
                layerVO.name = sLayer.name;
                layerVO.buildFromLayerVo(sLayer, _tilesets, _orientation);
                layerVO.x = sLayer.offsetx;
                layerVO.y = sLayer.offsety;
                _layers.push(layerVO);
                layerVO.StartPositon = new Vector2D(layerVO.x, layerVO.y);
                if (sLayer.properties.hasOwnProperty("layer"))
                {
                    addToLayer(layerVO, sLayer.properties["layer"], sLayer.properties["speedX"], sLayer.properties["speedY"]);
                }
                else
                {
                    _display.addChild(layerVO);
                }
            }
            dispatchEvent(new Event("complete"));
            DebugGrid();
        }

        private function addToLayer(_arg_1:TMXLayer, _arg_2:int, _arg_3:Number, _arg_4:Number):void
        {
            this[("layer" + _arg_2)].addChild(_arg_1);
        }

        public function DebugGrid():void
        {
            var _local_3:* = null;
            var _local_7:int;
            var _local_5:int;
            var _local_1:int;
            var _local_2:int;
            var _local_6:int;
            var _local_4:int;
            if (this._orientation == "isometric")
            {
                _local_3 = new Shape();
                this.Display.addChild(_local_3);
                _local_3.graphics.lineStyle(0.1, 0xCCCCCC);
                _local_6 = 0;
                while (_local_6 < this._mapHeight + 1)
                {
                    _local_7 = int(((this._mapHeight - _local_6) * this._tileWidth) / 2);
                    _local_5 = int((_local_6 * this._tileHeight) / 2);
                    _local_1 = int(_local_7 + (this._mapWidth * this._tileWidth) / 2);
                    _local_2 = int(_local_5 + (this._mapWidth * this._tileHeight) / 2);
                    _local_3.graphics.moveTo(_local_7, _local_5);
                    _local_3.graphics.lineTo(_local_1, _local_2);
                    _local_6++;
                }
                _local_4 = 0;
                while (_local_4 < this._mapWidth + 1)
                {
                    _local_7 = int((this._mapHeight * this._tileWidth) / 2 + (_local_4 * _tileWidth) / 2);
                    _local_5 = int((_local_4 * this._tileHeight) / 2);
                    _local_1 = int((_local_4 * this._tileWidth) / 2);
                    _local_2 = int(_local_5 + (this._mapHeight * this._tileHeight) / 2);
                    _local_3.graphics.moveTo(_local_7, _local_5);
                    _local_3.graphics.lineTo(_local_1, _local_2);
                    _local_4++;
                }
            }
        }

        protected function getDataLayerClass(_arg_1:LayerVO):Class
        {
            return TMXLayer;
        }

        public function get layers():Vector.<TMXLayer>
        {
            return _layers;
        }

        public function get objectLayers():Vector.<ObjectLayerVO>
        {
            return _objectLayers;
        }

        public function get MouseEnabled():Boolean
        {
            return mouseEnabled;
        }

        public function set MouseEnabled(_arg_1:Boolean):void
        {
            mouseEnabled = _arg_1;
            var _local_2:* = false;
            this._display.mouseChildren = _local_2;
            this._display.mouseEnabled = _local_2;
        }

        public function getObjectLayerByName(_arg_1:String):ObjectLayerVO
        {
            var _local_3:int;
            var _local_2:* = null;
            _local_3 = 0;
            while (_local_3 < _objectLayers.length)
            {
                _local_2 = _objectLayers[_local_3];
                if (_local_2.name == _arg_1)
                {
                    return _local_2;
                }
                _local_3++;
            }
            return null;
        }

        public function getObjectVo(_arg_1:Vector.<ObjectVO>, _arg_2:String):ObjectVO
        {
            var _local_4:int;
            var _local_3:* = null;
            _local_4 = 0;
            while (_local_4 < _arg_1.length)
            {
                _local_3 = _arg_1[_local_4];
                if (_local_3.name == _arg_2)
                {
                    return _local_3;
                }
                _local_4++;
            }
            return null;
        }

        public function destroy():void
        {
            var _local_2:int;
            var _local_1:int;
            this._display.removeChildren();
            _local_2 = 0;
            while (_local_2 < _layers.length)
            {
                _layers[_local_2].destroy();
                _local_2++;
            }
            _local_1 = 0;
            while (_local_1 < _layerVos.length)
            {
                _layerVos[_local_1].Destroy();
                _local_1++;
            }
            _layerVos.length = 0;
            _layerVos = null;
            _layers.splice(0, _layers.length);
            _layers = null;
            _XML = null;
            _tilesets.splice(0, _tilesets.length - 1);
            _tilesets = null;
            if (tmxRes)
            {
                tmxRes.destroy();
            }
            tmxRes = null;
        }

        public function getBound():Rectangle
        {
            return new Rectangle(0, 0, _mapWidth * _tileWidth, _mapHeight * _tileHeight);
        }

        public function GetLayerByName(_arg_1:String):TMXLayer
        {
            var _local_3:int;
            var _local_2:* = null;
            _local_3 = 0;
            while (_local_3 < _layers.length)
            {
                _local_2 = _layers[_local_3];
                if (_local_2.name == _arg_1)
                {
                    return _local_2;
                }
                _local_3++;
            }
            return null;
        }

        public function GetLayerByNames(_arg_1:String):Array
        {
            var _local_4:int;
            var _local_2:* = null;
            var _local_3:Array = [];
            _local_4 = 0;
            while (_local_4 < _layers.length)
            {
                _local_2 = _layers[_local_4];
                if (_local_2.name == _arg_1)
                {
                    _local_3.push(_local_2);
                }
                _local_4++;
            }
            return _local_3;
        }

        public function DrawNape():void
        {
            var _local_2:int;
            var _local_1:* = null;
            _local_2 = 0;
            while (_local_2 < this.layers.length)
            {
                _local_1 = this.layers[_local_2];
                if (_local_1.name == "Ground" || _local_1.name == "Floor" || _local_1.name == "Wall" || _local_1.name == "MEdge")
                {
                    Nape.getIns().shapeFactory.createByTmxLayer(_local_1.layerVo as ObjectLayerVO, 1);
                }
                _local_2++;
            }
        }

        public function UpdateFrontLayerOpacity(_arg_1:Rectangle, _arg_2:Vector.<GameObject>):void
        {
            var _local_11:* = null;
            var _local_15:* = null;
            var _local_8:* = null;
            var _local_3:* = null;
            var _local_4:Number;
            var _local_13:Number;
            var _local_14:* = null;
            var _local_5:int;
            var _local_7:* = null;
            var _local_6:int;
            var _local_9:int;
            var _local_10:int;
            var _local_12:* = 1;
            while (_local_10 < layer4.numChildren)
            {
                _local_11 = layer4.getChildAt(_local_10);
                if (_local_11 is TMXLayer)
                {
                    _local_15 = (_local_11 as TMXLayer);
                    if (_local_15.layerVo.properties.hasOwnProperty("barrierAlpha"))
                    {
                        _local_12 = _local_15.layerVo.properties["barrierAlpha"];
                        _local_8 = _local_15.layerVo.properties.noTriggerTags;
                        if (_local_8 && !(_local_8 == ""))
                        {
                            _local_3 = _local_8.split(";");
                        }
                        _local_4 = 1;
                        if (_local_15.layerVo.properties.hasOwnProperty("barrierOutAlpha"))
                        {
                            _local_4 = _local_15.layerVo.properties["barrierOutAlpha"];
                        }
                        _local_13 = 0;
                        _local_14 = [];
                        _local_5 = 0;
                        while (_local_5 < _arg_2.length)
                        {
                            if (!(_arg_2[_local_5].campId < 1 || _arg_2[_local_5].tags.indexOf("magicWeapon") > -1))
                            {
                                _local_7 = new Rectangle(_arg_2[_local_5].Position.x - 40, _arg_2[_local_5].Position.y - 80, 80, 80);
                                if (_local_11.getBounds(_local_11.parent).intersects(_local_7))
                                {
                                    _local_14.push(_arg_2[_local_5]);
                                }
                            }
                            _local_5++;
                        }
                        _local_6 = 0;
                        while (_local_6 < _local_14.length)
                        {
                            if (_local_3)
                            {
                                _local_9 = 0;
                                while (_local_9 < _local_3.length)
                                {
                                    if (_local_14[_local_6].tags.indexOf(_local_3[_local_9]) <= -1)
                                    {
                                        _local_4 = _local_12;
                                        break;
                                    }
                                    _local_9++;
                                }
                            }
                            else
                            {
                                _local_4 = _local_12;
                            }
                            _local_6++;
                        }
                        _local_14 = null;
                        _local_11.alpha = _local_4;
                    }
                }
                _local_10++;
            }
        }

        public function UpdatePos(mapX:Number, mapY:Number, camaraScale:Number):void
        {
            var point:Point;
            for (var i:int = 0; i < _layers.length; i++)
            {
                var sLayer:TMXLayer = _layers[i];
                sLayer.x = sLayer.StartPositon.x - (mapX * sLayer.SpeeX) / camaraScale;
                sLayer.y = sLayer.StartPositon.y - (mapY * sLayer.SpeeY) / camaraScale;
                if (sLayer.layerVo.properties.hasOwnProperty("isFixedX"))
                {
                    if (sLayer.layerVo.properties.isFixedX == true)
                    {
                        point = sLayer.localToGlobal(new Point());
                        sLayer.x = -(point.x + sLayer.StartPositon.x);
                    }
                }
                if (sLayer.layerVo.properties.hasOwnProperty("isFixedY"))
                {
                    if (sLayer.layerVo.properties.isFixedY == true)
                    {
                        point = sLayer.localToGlobal(new Point());
                        sLayer.y = -(point.y + sLayer.StartPositon.y);
                    }
                }
                if (sLayer.layerVo.properties.hasOwnProperty("isFixedScreen"))
                {
                    if (sLayer.layerVo.properties.isFixedScreen == true)
                    {
                        sLayer.x = -mapX;
                    }
                }
                if (sLayer.layerVo.properties.hasOwnProperty("inside_loop"))
                {
                    sLayer.Update();
                }
                sLayer.MoveByInsideobj();
            }
        }

        public function checkDel(_arg_1:int):void
        {
            var _local_3:int;
            var _local_2:* = null;
            _local_3 = _layers.length - 1;
            while (_local_3 >= 0)
            {
                _local_2 = _layers[_local_3].layerVo;
                if (_local_2 && _local_2.properties.hasOwnProperty("delNoScreen"))
                {
                    SimpleTextLog.getIns().log2("delNoScreen", "noscreen=" + _arg_1, _local_2.name + "=" + _local_2.properties.delNoScreen);
                    if (_arg_1 != _local_2.properties.delNoScreen)
                    {
                        _layers[_local_3].destroy();
                        _layers.splice(_local_3, 1);
                    }
                }
                _local_3--;
            }
        }


    }
}//package com.wdcgame.tile

